package com.junmeng.generic;

import org.junit.jupiter.api.Assertions;

import java.lang.reflect.Type;
import java.util.ArrayList;

public class JGenericUtilTest2 {

    public interface InterA<T> {

    }

    public static class InterA1Impl<T> implements InterA<T> {
    }

    public static class InterA2Impl implements InterA<String> {
    }

    public static class InterA3Impl implements InterA<ArrayList<String>> {
    }

    public static class InterA4Impl implements InterA<ArrayList<String>>, Runnable {

        @Override
        public void run() {

        }
    }

    public static class InterA5Impl implements Runnable, InterA<ArrayList<String>> {

        @Override
        public void run() {

        }
    }

    public static class B extends InterA5Impl {
    }


    public interface InterC1 extends InterA {
    }

    public interface InterC2 extends InterA<String> {
    }

    public interface InterC3 extends InterA<ArrayList<String>> {
    }

    public interface InterC4<T> extends InterA<T> {
    }

    public static class InterC4Impl<T> implements InterC4<T> {
    }

    public static class InterC41Impl implements InterC4<ArrayList<String>> {
    }

    @org.junit.jupiter.api.Test
    public void testGetInterfaceGenericType1() {

        Type type1 = JGenericUtil.getInterfaceGenericType(new InterA<ArrayList<String>>() {
        }.getClass(), InterA.class, 0);
        System.out.println("type=" + type1);//type=java.util.ArrayList<java.lang.String>
        Assertions.assertEquals(type1.toString(), "java.util.ArrayList<java.lang.String>");

        Type type2 = JGenericUtil.getInterfaceGenericType(new InterA1Impl<ArrayList<String>>().getClass(), InterA.class, 0);
        System.out.println("type=" + type2);//type=T
        Assertions.assertEquals(type2.toString(), "T");

        Type type3 = JGenericUtil.getInterfaceGenericType(new InterA2Impl().getClass(), InterA.class, 0);
        System.out.println("type=" + type3);//type=class java.lang.String
        Assertions.assertEquals(type3.toString(), "class java.lang.String");

        Type type4 = JGenericUtil.getInterfaceGenericType(new InterA3Impl().getClass(), InterA.class, 0);
        System.out.println("type=" + type4);//type=java.util.ArrayList<java.lang.String>
        Assertions.assertEquals(type4.toString(), "java.util.ArrayList<java.lang.String>");

        Type type5 = JGenericUtil.getInterfaceGenericType(new InterA4Impl().getClass(), InterA.class, 0);
        System.out.println("type=" + type5);//type=java.util.ArrayList<java.lang.String>
        Assertions.assertEquals(type5.toString(), "java.util.ArrayList<java.lang.String>");

        Type type6 = JGenericUtil.getInterfaceGenericType(new InterA5Impl().getClass(), InterA.class, 0);
        System.out.println("type=" + type6);//type=java.util.ArrayList<java.lang.String>
        Assertions.assertEquals(type6.toString(), "java.util.ArrayList<java.lang.String>");
    }

    @org.junit.jupiter.api.Test
    public void testGetInterfaceGenericType2() {

        Type type1 = JGenericUtil.getInterfaceGenericType(new B().getClass(), InterA.class, 0);
        System.out.println("type=" + type1);//type=java.util.ArrayList<java.lang.String>
        Assertions.assertEquals(type1.toString(), "java.util.ArrayList<java.lang.String>");

        Type type2 = JGenericUtil.getInterfaceGenericType(new InterC1() {
        }.getClass(), InterA.class, 0);
        System.out.println("type=" + type2);//type=null
        Assertions.assertEquals(type2, null);

        Type type3 = JGenericUtil.getInterfaceGenericType(new InterC2() {
        }.getClass(), InterA.class, 0);
        System.out.println("type=" + type3);//type=class java.lang.String
        Assertions.assertEquals(type3.toString(), "class java.lang.String");

        Type type4 = JGenericUtil.getInterfaceGenericType(new InterC3() {
        }.getClass(), InterA.class, 0);
        System.out.println("type=" + type4);//type=java.util.ArrayList<java.lang.String>
        Assertions.assertEquals(type4.toString(), "java.util.ArrayList<java.lang.String>");

        Type type5 = JGenericUtil.getInterfaceGenericType(new InterC4<String>() {
        }.getClass(), InterA.class, 0);
        System.out.println("type=" + type5);//type=T
        Assertions.assertEquals(type5.toString(), "T");

        Type type6 = JGenericUtil.getInterfaceGenericType(new InterC4Impl<String>().getClass(), InterA.class, 0);
        System.out.println("type=" + type6);//type=T
        Assertions.assertEquals(type6.toString(), "T");

        Type type7 = JGenericUtil.getInterfaceGenericType(new InterC41Impl().getClass(), InterA.class, 0);
        System.out.println("type=" + type7);//type=T
        Assertions.assertEquals(type7.toString(), "T");
    }
}
